#ifndef COLLISIONFACTORY_H
#define COLLISIONFACTORY_H

#include "Collision1D_Coulomb.h"
#include "Collision1D_Ionization.h"
#include "Collision1D_Excitation.h"
#include "Collision1D_ChargeExchange.h"

#include "Collision1D_Ionization_Fluid.h"
#include "Collision1D_Ionization_Notnull.h"

#include <string>
#include <cmath>
#include <iomanip>
#include <algorithm>
#include <ostream>
#include <sstream>
using namespace std;

class CollisionFactory
{

public:

    static vector<Collision*> create(PicParams* params_, ParallelMPI* pmpi_, vector<Species*>* vecSpecies_)
	{
	    vector<Collision*> vecCollision;

        for (int i_collision = 0; i_collision < params_->collision_param.size(); i_collision++)
		{
            auto collision_param_ = params_->collision_param[i_collision];

            if(params_->geometry == "1d3v" && collision_param_.collision_type == "coulomb")
			{
                vecCollision.push_back( new Collision1D_Coulomb(params_, collision_param_, i_collision) );
			}

            else if(params_->geometry == "1d3v" && collision_param_.collision_type == "ionization")
            {
                vecCollision.push_back( new Collision1D_Ionization(params_, collision_param_, i_collision) );
            }

            else if(params_->geometry == "1d3v" && collision_param_.collision_type == "ionization_fluid")
            {
                vecCollision.push_back( new Collision1D_Ionization_Fluid(params_, collision_param_, i_collision) );
            }

            else if(params_->geometry == "1d3v" && collision_param_.collision_type == "ionization_notnull")
            {
                vecCollision.push_back( new Collision1D_Ionization_Notnull(params_, collision_param_, i_collision) );
            }

            else if(params_->geometry == "1d3v" && collision_param_.collision_type == "excitation")
            {
                vecCollision.push_back( new Collision1D_Excitation(params_, collision_param_, i_collision) );
            }

            else if(params_->geometry == "1d3v" && collision_param_.collision_type == "charge_exchange")
            {
                vecCollision.push_back( new Collision1D_ChargeExchange(params_, collision_param_, i_collision) );
            }

            else
            {
                log_info<<"no collision type : " << collision_param_.collision_type;
			}
	    }
        log_info<<"number of collisions is : "<<vecCollision.size();
	    return vecCollision;
	};

};

#endif
